package cn.jingyuan.owl.model.paging;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * 分页结果
 * // fixme 参考：https://www.cnblogs.com/BillySir/p/14418811.html
 */
public class Page<E> implements Serializable {

    /** 当前页 */
    private final int page;

    /** 每页显示多少条 */
    private final int pageSize;

    /** 总页数 */
    private final int pageCount;

    /** 总记录数 */
    private final int totalCount;

    /** 本页的数据列表 */
    private List<E> records = new ArrayList<>();

    /** 页码列表的开始索引(包含) */
    private int pageIndexBegin;

    /** 页码列表的结束索引(包含) */
    private int pageIndexEnd;

    /** 当前分页条件下的统计结果 */
    private Map<String, E> countResultMap;

    /**
     * 只接受前 4 个必要的属性，会自动计算出其他 3 个属性的值
     *
     * @param page 当前页
     * @param pageSize 每页显示多少条
     * @param totalCount 总页数
     * @param records 本页的数据列表
     */
    public Page(int page, int pageSize, int totalCount, List<E> records) {
        this.page = page;
        this.pageSize = pageSize;
        this.totalCount = totalCount;
        this.records = records;

        // 计算总页码
        pageCount = (totalCount + pageSize - 1) / pageSize;

        // 计算 beginPageIndex 和 endPageIndex
        // >> 总页数不多于10页，则全部显示
        if (pageCount <= 10) {
            pageIndexBegin = 1;
            pageIndexEnd = pageCount;
        }
        // >> 总页数多于10页，则显示当前页附近的共10个页码
        else {
            // 当前页附近的共10个页码（前4个 + 当前页 + 后5个）
            pageIndexBegin = page - 4;
            pageIndexEnd = page + 5;
            // 当前面的页码不足4个时，则显示前10个页码
            if (pageIndexBegin < 1) {
                pageIndexBegin = 1;
                pageIndexEnd = 10;
            }
            // 当后面的页码不足5个时，则显示后10个页码
            if (pageIndexEnd > pageCount) {
                pageIndexEnd = pageCount;
                pageIndexBegin = pageCount - 10 + 1;
            }
        }
    }

    /**
     * 只接受前 5 个必要的属性，会自动计算出其他 3 个属性的值
     *
     * @param page 当前页
     * @param pageSize 每页显示多少条
     * @param totalCount 总记录数
     * @param records 本页的数据列表
     */
    public Page(int page, int pageSize, int totalCount, List<E> records, Map<String, E> countResultMap) {
        this.page = page;
        this.pageSize = pageSize;
        this.totalCount = totalCount;
        this.records = records;
        this.countResultMap = countResultMap;

        // 计算总页码
        pageCount = (totalCount + pageSize - 1) / pageSize;

        // 计算 beginPageIndex 和 endPageIndex
        // >> 总页数不多于 10 页，则全部显示
        if (pageCount <= 10) {
            pageIndexBegin = 1;
            pageIndexEnd = pageCount;
        } else {
            // >> 总页数多于 10 页，则显示当前页附近的共 10 个页码
            // 当前页附近的共10个页码（前 4 个 + 当前页 + 后 5 个）
            pageIndexBegin = page - 4;
            pageIndexEnd = page + 5;
            // 当前面的页码不足4个时，则显示前 10 个页码
            if (pageIndexBegin < 1) {
                pageIndexBegin = 1;
                pageIndexEnd = 10;
            }
            // 当后面的页码不足5个时，则显示后 10 个页码
            if (pageIndexEnd > pageCount) {
                pageIndexEnd = pageCount;
                pageIndexBegin = pageCount - 10 + 1;
            }
        }
    }

    public int getPage() {
        return page;
    }

    public int getPageSize() {
        return pageSize;
    }

    public int getPageCount() {
        return pageCount;
    }

    public int getTotalCount() {
        return totalCount;
    }

    public List<E> getRecords() {
        return records;
    }

    public int getPageIndexBegin() {
        return pageIndexBegin;
    }

    public int getPageIndexEnd() {
        return pageIndexEnd;
    }

    public Map<String, E> getCountResultMap() {
        return countResultMap;
    }

}